package com.git.hui.yinshua.biz.user.dao.repository;

import com.git.hui.yinshua.api.model.ExceptionUtil;
import com.git.hui.yinshua.api.model.Status;
import com.git.hui.yinshua.api.model.constants.GlobalConstants;
import com.git.hui.yinshua.biz.rest.models.user.res.UserAddressDto;
import com.git.hui.yinshua.biz.user.dao.domain.UserAddressEntity;
import com.git.hui.yinshua.biz.user.dao.mapper.UserAddressMapper;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.git.hui.yinshua.api.model.constants.GlobalConstants.AddressApi.MAIN_ADDRESS;
import static com.git.hui.yinshua.api.model.constants.GlobalConstants.AddressApi.NORMAL_ADDRESS;

/**
 * @author YiHui
 * @date 2024/6/11
 */
@Repository
public class UserAddressRepository {
    @Autowired
    private UserAddressMapper userAddressMapper;

    public UserAddressEntity queryAddress(Integer addressId) {
        return userAddressMapper.queryAddressById(addressId);
    }

    /**
     * 查询用户的地址列表
     *
     * @param userId
     * @return
     */
    public List<UserAddressEntity> queryUserAddressList(Integer userId) {
        return userAddressMapper.listUserAddress(userId);
    }

    /**
     * 批量查询用户地址
     *
     * @param userIdList
     * @return
     */
    public Map<Integer, List<UserAddressEntity>> batchQueryUserAddressList(List<Integer> userIdList) {
        List<UserAddressEntity> list = userAddressMapper.batchListUserAddress(userIdList);
        return list.stream().collect(Collectors.groupingBy(UserAddressEntity::getUid));
    }

    /**
     * 查询默认地址, 若没有默认地址，则取最近创建的一个
     *
     * @param userId
     * @return
     */
    public UserAddressEntity queryMainAddress(Integer userId) {
        return userAddressMapper.queryMainAddress(userId);
    }

    /**
     * 添加用户地址
     *
     * @param userId  用户
     * @param address 用户地址
     */
    public void addAddress(Integer userId, UserAddressDto address) {
        UserAddressEntity userAddress = new UserAddressEntity();
        userAddress.setUid(userId);
        userAddress.setReceivingPerson(address.getPerson());
        userAddress.setReceivingPhone(address.getPhone());
        userAddress.setReceivingArea(address.getArea());
        userAddress.setReceivingAddress(address.getAddress());
        userAddress.setReceivingTag(address.getTag());
        userAddress.setMainAddress(BooleanUtils.isTrue(address.getDefaultAddress()) ? MAIN_ADDRESS : NORMAL_ADDRESS);

        if (Objects.equals(userAddress.getMainAddress(), MAIN_ADDRESS)) {
            // 新增一个默认地址，则需要将之前的默认地址标记为非默认地址
            Optional.ofNullable(queryMainAddress(userId)).ifPresent(s -> {
                s.setMainAddress(NORMAL_ADDRESS);
                userAddressMapper.updateAddress(s);
            });
        }
        userAddressMapper.addAddress(userAddress);
    }

    /**
     * 地址更新
     *
     * @param userId      登录用户
     * @param userAddress 用户地址
     */
    public void updateAddress(Integer userId, UserAddressDto userAddress) {
        UserAddressEntity entity = new UserAddressEntity();
        entity.setId(userAddress.getAddressId())
                .setUid(userId)
                .setReceivingPerson(userAddress.getPerson())
                .setReceivingPhone(userAddress.getPhone())
                .setReceivingArea(userAddress.getArea())
                .setReceivingAddress(userAddress.getAddress())
                .setReceivingTag(userAddress.getTag());
        if (BooleanUtils.isTrue(userAddress.getDefaultAddress())) {
            // 更新默认地址，则需要将之前的默认地址标记为非默认地址
            Optional.ofNullable(queryMainAddress(userId)).ifPresent(s -> {
                if (!Objects.equals(s.getId(), userAddress.getAddressId())) {
                    s.setMainAddress(NORMAL_ADDRESS);
                    userAddressMapper.updateAddress(s);
                }
            });
            entity.setMainAddress(MAIN_ADDRESS);
        } else {
            entity.setMainAddress(NORMAL_ADDRESS);
        }

        userAddressMapper.updateAddress(entity);
    }

    /**
     * 更新默认地址
     *
     * @param userId      用户
     * @param addressId   地址
     * @param markDefault true表示设置为默认地址， false表示取消默认地址设置
     */
    public void updateMainAddress(Integer userId, Integer addressId, Boolean markDefault) {
        UserAddressEntity address = userAddressMapper.queryAddressById(addressId);
        if (!Objects.equals(address.getUid(), userId)) {
            // 更新的不是自己的地址
            throw ExceptionUtil.of(Status.StatusEnum.FORBID_ERROR);
        }
        if (markDefault) {
            // 将地址标记为默认地址
            if (Objects.equals(address.getMainAddress(), NORMAL_ADDRESS)) {
                // 待更新的地址为非默认地址， 则需要将现有的默认地址更新为非默认地址
                Optional.ofNullable(queryMainAddress(userId)).ifPresent(oldMainAddr -> {
                    if (!Objects.equals(oldMainAddr.getId(), addressId)) {
                        oldMainAddr.setMainAddress(NORMAL_ADDRESS);
                        userAddressMapper.updateAddress(oldMainAddr);
                    }
                });
                // 更新当前地址为默认地址
                userAddressMapper.updateMainAddress(userId, addressId, MAIN_ADDRESS);
            }
        } else {
            // 只有当前地址为默认地址，才需要执行取消默认地址动作
            if (Objects.equals(address.getMainAddress(), MAIN_ADDRESS)) {
                userAddressMapper.updateMainAddress(userId, addressId, NORMAL_ADDRESS);
            }
        }
    }

    /**
     * 删除地址
     *
     * @param userId    用户id
     * @param addressId 地址id
     */
    public boolean removeAddress(Integer userId, Integer addressId) {
        UserAddressEntity address = userAddressMapper.queryAddressById(addressId);
        if (address.getDeleted() == GlobalConstants.DELETED_TAG) {
            return true;
        }
        if (!Objects.equals(address.getUid(), userId)) {
            // 更新的不是自己的地址
            throw ExceptionUtil.of(Status.StatusEnum.FORBID_ERROR);
        }
        return userAddressMapper.rmAddress(userId, addressId) > 0;
    }
}
